/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#ifndef __HARDWARE_DEPENDENT_OBJECT_H__
#define __HARDWARE_DEPENDENT_OBJECT_H__

#include <vector>
#include <Gluck.h>
#include <NoCopy.h>

namespace liba
{

template<class Ha>
class HardwareDependentObjectBase
{
public:
	virtual void on_add_hardware(Ha * ha)=0;
	virtual void on_remove_hardware(Ha * ha)=0;
};


template<class Man, class Data>
class HardwareDependentObject : public HardwareDependentObjectBase<typename Man::hardware_type>, private NoAssign
{
public:
	//on a copy the object doesn't get any buffers, it's up to the derived class to register in a hardware again
	HardwareDependentObject(const HardwareDependentObject & other)
	{}
	HardwareDependentObject()
	{}

	typedef typename Man::hardware_type hardware_type;
	typedef std::pair<hardware_type *, Data *> SweetPair;
	typedef std::vector< SweetPair > HardVector;

	/** Never returns 0 */
	Data * find_data(hardware_type * ha)
	{
		typename HardVector::iterator it = hard_vector.begin();
		for( ;it != hard_vector.end(); ++it )
			if( it->first == ha )
				return it->second;
		THROW(Gluck(__FUNCTION__, "Data not found" ));
	}
protected:
	HardVector hard_vector;
	virtual void on_remove_hardware(hardware_type * ha)
	{
		typename HardVector::iterator it = hard_vector.begin();
		while( it != hard_vector.end() )
			if( it->first == ha )
			{
				delete it->second;
				it = hard_vector.erase( it );
			}
			else
				++it;
	}
};

} // namespace liba
using namespace liba;

#endif // __HARDWARE_DEPENDENT_OBJECT_H__

